"""
model name : aihw
file       : base.py
information: 这是一个用于建立围棋棋盘大小的棋盘地图，他的起始坐标为左下角（1， 1）
            This is a cheep map, the point (1, 1) of the bottem left is a start point.
    author : OuYang
    time   : 2025/10/9
"""
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from utils.utils import index2corr, idx2rgba


class Map:
    def __init__(self, basemap, col=19, row=19, width=1):
        self.col = col
        self.row = row
        self.__width = width

        if basemap:
            self.__map = basemap
        else:
            self.__map = \
                [
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                    [1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1],
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1],
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1],
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1],
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1],
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1],
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1],
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1],
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1],
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1],
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1],
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1],
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                ]

        # 计墙的位置
        self.__walls = []
        for i in range(self.col):
            for j in range(self.row):
                if self.__map[i][j] == -1:
                    self.__walls.append(index2corr(i, j))

        # 路径列表
        self.road_list = []

        # 绘制相关
        self.__plotted = False

        # 初始化画布
        a = self.__width + self.col
        self.__fig, self.__ax = plt.subplots(figsize=(a, a))

    def add_rect(self, x, y):
        self.road_list.append((x, y))

    def add_rects(self, road_list: list):
        rects = []
        for road in road_list:
            if not isinstance(road, tuple):
                raise TypeError('type must be a tuple')
            rects.append(road)
        self.road_list.extend(rects)

    def clear_rects(self):
        self.road_list = []

    def plot_map(self, width=1, showeight=False, wallcolor='#afabac'):
        self.__width = width
        a = self.col + self.__width
        half_width = self.__width / 2

        # 绘制地图
        for i in range(a):
            # 横线
            plt.plot([half_width, a - half_width], [i + half_width, i + half_width], 'k-', linewidth=1)
            # 竖线
            plt.plot([i + half_width, i + half_width], [half_width, a - half_width], 'k-', linewidth=1)

        # 绘制墙体
        for pos in self.__walls:
            # x, y = pos
            # x, y = x - half_width, y - half_width
            # rect = Rectangle((x, y), self.__width, self.__width, linewidth=-1, color=wallcolor)
            # self.__ax.add_patch(rect)
            self.plot_rect(pos, c=wallcolor)

        # 显示权重
        if showeight:
            for i in range(self.col):
                for j in range(self.row):
                    if (i == self.col - 1 and j == 0) or (i == 0 and j == self.row - 1):
                        continue
                    if self.__map[i][j] != -1:
                        x, y = index2corr(i, j)
                        self.__ax.text(x, y, f'{self.__map[i][j]}', ha='center', va='center', fontsize=24,
                                       fontweight='bold')

        # 标识起点和终点
        self.__ax.text(1, 1, 'S', ha='center', va='center', fontsize=24, fontweight='bold')
        self.__ax.text(self.col, self.row, 'E', ha='center', va='center', fontsize=24, fontweight='bold')

        # 取消坐标轴
        self.__ax.set_xticks([])
        self.__ax.set_yticks([])

        self.__plotted = True

    def plot_rect(self, pos, c):
        x, y = pos
        x, y = x - self.__width / 2, y - self.__width / 2
        rect = Rectangle((x, y), self.__width, self.__width, linewidth=-1, color=c)
        self.__ax.add_patch(rect)

    def plot_rects(self, rsc=(0, 255, 0), rec=(0, 0, 255)):
        if not self.__plotted:
            raise Exception('Not plotted, Please call plot_map()')
        # 绘制路径
        if len(self.road_list) > 0:
            for i, pos in enumerate(self.road_list):
                # 生成渐变颜色
                c = idx2rgba(i, len(self.road_list), sc=rsc, ec=rec)

                self.plot_rect(pos, c)

                # x, y = pos
                # x, y = x - self.__width / 2, y - self.__width / 2
                # rect = Rectangle((x, y), self.__width, self.__width, linewidth=-1, color=c)
                # self.__ax.add_patch(rect)

    def show(self):
        if not self.__plotted:
            raise Exception('Not plotted, Please plot')
        plt.show()
        # plt.savefig("image.png")

    def save(self, filename, dpi=400):
        if not self.__plotted:
            raise Exception('Not plotted, Please call plot()')

        plt.savefig(filename, dpi=dpi, bbox_inches='tight')
        print(f'Saved image to {filename}')

    def close(self):
        plt.close(self.__fig)


if __name__ == '__main__':
    map = Map()
    map.add_rect(1, 1)
    map.add_rects([(1, 2)])
    map.show(showight=True)
